package com.niiwoo.civet.user.service.local;

import cn.jiguang.common.DeviceType;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.user.dao.entity.MarketingPushUser;
import com.niiwoo.civet.user.dao.entity.MessageTemplate;
import com.niiwoo.civet.user.dao.entity.UserInstationLetter;
import com.niiwoo.civet.user.dao.mapper.JPushRecordMapper;
import com.niiwoo.civet.user.dao.mapper.MarketingPushUserMapper;
import com.niiwoo.civet.user.dao.mapper.MessageTemplateMapperExt;
import com.niiwoo.civet.user.dao.mapper.UserInstationLetterMapperExt;
import com.niiwoo.civet.user.dto.request.MarketingJPushRequestDTO;
import com.niiwoo.civet.user.dto.request.MarketingPushLetterRequestDTO;
import com.niiwoo.civet.user.dto.request.SearchUserLetterListRequestDTO;
import com.niiwoo.civet.user.dto.request.UserLetterRequestDTO;
import com.niiwoo.civet.user.dto.response.UserExtInfoResponseDTO;
import com.niiwoo.civet.user.dto.response.ValidUserForbidResponseDTO;
import com.niiwoo.civet.user.enums.UserForbidTypeEnum;
import com.niiwoo.civet.user.service.UserExtInfoDubboService;
import com.niiwoo.tripod.push.component.JpushClients;
import com.niiwoo.tripod.push.model.PushTarget;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Exchange;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 站内信与极光推送服务
 *
 * @author xueyuke
 * @since 2017-12-15
 */
@Service
public class UserLetterService {

    private final static Logger logger = LoggerFactory.getLogger(UserLetterService.class);

    @Autowired
    JpushClients jpushClients;
    @Autowired
    UserInstationLetterMapperExt userInstationLetterMapper;
    @Autowired
    JPushRecordMapper jPushRecordMapper;
    @Autowired
    MessageTemplateMapperExt messageTemplateMapper;
    @Autowired
    SnowflakeIdWorker snowflakeIdWorker;
    @Reference(version = "1.0.0")
    UserExtInfoDubboService userExtInfoDubboService;
    @Autowired
    MarketingPushUserMapper marketingPushUserMapper;
    @Autowired
    UserForbidService userForbidService;

    /**
     * 推送站内信
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    public void pushLetter(UserLetterRequestDTO userLetterRequestDTO) {
        try{
            MessageTemplate messageTemplate=messageTemplateMapper.selectByTemplateKey(userLetterRequestDTO.getLetterTemplateEnum().getKey());
            if(messageTemplate==null){
                logger.error("发送站内信,目标用户ID={},发生异常,原因是模板不存在,模板Key={}",userLetterRequestDTO.getToUserId(),userLetterRequestDTO.getLetterTemplateEnum().getKey());
                throw new RuntimeException("模板不存在,模板key=".concat(userLetterRequestDTO.getLetterTemplateEnum().getKey()));
            }

            String messageContent = messageTemplate.getTemplateContent();
			if (!CollectionUtils.isEmpty(userLetterRequestDTO.getLetterTemplateParamList())) {
				messageContent = String.format(messageTemplate.getTemplateContent(), userLetterRequestDTO.getLetterTemplateParamList().toArray());	
            }

            UserInstationLetter userInstationLetter=new UserInstationLetter();
            userInstationLetter.setId(snowflakeIdWorker.nextId());
            userInstationLetter.setTitle(messageTemplate.getTemplateTitle());
            userInstationLetter.setContent(messageContent);
            userInstationLetter.setSendDate(new Date());
            userInstationLetter.setToUserId(userLetterRequestDTO.getToUserId());
            userInstationLetter.setIsRead((byte)0);
            userInstationLetter.setIsShowRedPoint((byte)1);
            userInstationLetter.setMessageType((byte)0);
            userInstationLetter.setAppbuttons(JSON.toJSONString(userLetterRequestDTO.getLetterButtonList()));
            userInstationLetter.setCreateTime(new Date());

            userInstationLetterMapper.insertSelective(userInstationLetter);
        }catch (Exception e){
            logger.error("发送站内信发生异常,消息内容:{}",userLetterRequestDTO.toString(),e);
        }
    }

    /**
     * 极光推送
     * @param
     */
    public void jpush(UserLetterRequestDTO userLetterRequestDTO) {
        try {
        	// 禁止登录的用户不进行极光推送消息
        	ValidUserForbidResponseDTO forbidRecord = userForbidService.queryValidUserForbidInfo(userLetterRequestDTO.getToUserId(), UserForbidTypeEnum.LOGIN);
        	if (forbidRecord != null) {
        		logger.info("极光推送,目标用户ID={},用户存在禁止登陆行为不推送。",userLetterRequestDTO.getToUserId());
                return;
        	}
        	
            MessageTemplate messageTemplate=messageTemplateMapper.selectByTemplateKey(userLetterRequestDTO.getJpushTemplateKeyEnum().getKey());
            if(messageTemplate==null){
                logger.error("极光推送,目标用户ID={},发生异常,原因是模板不存在,模板Key={}",userLetterRequestDTO.getToUserId(),userLetterRequestDTO.getJpushTemplateKeyEnum().getKey());
                return;
            }
            String messageContent = messageTemplate.getTemplateContent();
            if (!CollectionUtils.isEmpty(userLetterRequestDTO.getJpushTemplateParamList())) {
				messageContent = String.format(messageTemplate.getTemplateContent(), userLetterRequestDTO.getJpushTemplateParamList().toArray());
            }
            UserExtInfoResponseDTO userExtInfoResponseDTO=userExtInfoDubboService.queryUserBasicInfo(userLetterRequestDTO.getToUserId());

            if(userExtInfoResponseDTO==null){
                logger.error("极光推送,目标用户ID={},发生异常,原因是用户扩展信息不存在",userLetterRequestDTO.getToUserId());
                return;
            }
            if(StringUtils.isEmpty(userExtInfoResponseDTO.getJiuangPushId())){
                logger.error("极光推送,目标用户ID={},发生异常,原因是用户极光推送ID不存在",userLetterRequestDTO.getToUserId());
                return;
            }
            // 获取设备类型优先取最后一次登录设备，如果最后一次登录设备为空取注册设备 
			DeviceType deviceType = transDeviceType(null != userExtInfoResponseDTO.getLastLoginDevice() ? userExtInfoResponseDTO.getLastLoginDevice()
							: userExtInfoResponseDTO.getDeviceType());
            if(deviceType==null){
                logger.error("极光推送,目标用户ID={},发生异常,原因是用户最后设备类型不是APP(IOS或安卓)",userLetterRequestDTO.getToUserId());
                return;
            }
            Map<String, String> extraMap = new HashMap<>();
            if(userLetterRequestDTO.getJPushExt() != null) {
                extraMap.put("redirectPage",userLetterRequestDTO.getJPushExt().getRedirectPage());
            }
            PushTarget pushTarget=new PushTarget(userExtInfoResponseDTO.getJiuangPushId(),deviceType);

            jpushClients.sendNotification(messageTemplate.getTemplateTitle(),messageContent,extraMap,pushTarget);
        }catch (Exception e){
            logger.error("极光推送发生异常,推送内容：{}",userLetterRequestDTO.toString(),e);
        }
    }

    public DeviceType transDeviceType(Byte lastLoginDevice){
        if(lastLoginDevice == null){
            return null;
        }

        if(lastLoginDevice.intValue()==0){
            return DeviceType.Android;
        }else if(lastLoginDevice.intValue()==1){
            return DeviceType.IOS;
        }

        return null;
    }

    /**
     * 查询用户站内信列表
     * @param searchUserLetterListRequestDTO
     * @return
     */
    @Transactional(isolation = Isolation.READ_COMMITTED,rollbackFor = Exception.class)
    public List<UserInstationLetter> queryUserLetterList(SearchUserLetterListRequestDTO searchUserLetterListRequestDTO){
        return userInstationLetterMapper.selectUserLetterList(searchUserLetterListRequestDTO);
    }

    /**
     * 查询用户站内信条数
     * @param searchUserLetterListRequestDTO
     * @return
     */
    @Transactional(isolation = Isolation.READ_COMMITTED,rollbackFor = Exception.class)
    public Integer queryUserLetterCount(SearchUserLetterListRequestDTO searchUserLetterListRequestDTO){
        return userInstationLetterMapper.selectUserLetterCount(searchUserLetterListRequestDTO);
    }

    /**
     * 查询用户未读消息数
     * @param userId
     * @return
     */
    public Integer queryRedPointCountByUserIdAndDate(String userId){
        return userInstationLetterMapper.selectRedPointCountByUserIdAndDate(userId);
    }

    /**
     * 根据时间去除站内信小红点
     * @param userId
     */
    public void deleteRedPointByUseId(String userId){
        //将用户所有的站内信置为已读;
        userInstationLetterMapper.deleteRedPointByUseIdAndDate(userId);
    }

    /**
     * 查询用户最新一条站内信
     * @param userId
     * @return
     */
    public UserInstationLetter queryUserLastOneLetter(String userId){
        return userInstationLetterMapper.selectLastOneByUserId(userId);
    }

    /**
     * 已读站内信
     * @param userLetterId
     */
    @Transactional
    public void readLetter(Long userLetterId){
        UserInstationLetter userInstationLetter=new UserInstationLetter();
        userInstationLetter.setId(userLetterId);
        userInstationLetter.setViewDate(new Date());
        userInstationLetter.setIsRead((byte)1);
        userInstationLetterMapper.updateByPrimaryKeySelective(userInstationLetter);
        UserInstationLetter letter=userInstationLetterMapper.selectByPrimaryKey(userLetterId);
        if(letter!=null&&letter.getPushUserId()!=null){
        	MarketingPushUser user=new MarketingPushUser();
    		user.setId(letter.getPushUserId());
    		user.setIsOpen((byte)1);
    		marketingPushUserMapper.updateByPrimaryKeySelective(user);
        }
        
    }

    /**
     * 删除站内信
     * @param userLetterIdList
     */
    public void deleteLetter(List<Long> userLetterIdList){
        for(Long userLetterId:userLetterIdList) {
            UserInstationLetter userInstationLetter = new UserInstationLetter();
            userInstationLetter.setId(userLetterId);
            userInstationLetter.setDelFlag((byte) 1);
            userInstationLetterMapper.updateByPrimaryKeySelective(userInstationLetter);
        }
    }

    /**
     * 推送站内信
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    public void pushMarketingLetter(MarketingPushLetterRequestDTO userLetterRequestDTO) {
        UserInstationLetter userInstationLetter=new UserInstationLetter();
        userInstationLetter.setId(snowflakeIdWorker.nextId());
        userInstationLetter.setTitle(userLetterRequestDTO.getTitle());
        userInstationLetter.setContent(userLetterRequestDTO.getContent());
        userInstationLetter.setSendDate(new Date());
        userInstationLetter.setToUserId(userLetterRequestDTO.getUserId());
        userInstationLetter.setIsRead((byte)0);
        userInstationLetter.setIsShowRedPoint((byte)1);
        userInstationLetter.setMessageType((byte)0);
        //userInstationLetter.setAppbuttons(JSON.toJSONString(userLetterRequestDTO.getLetterButtonList()));
        userInstationLetter.setCreateTime(new Date());

        userInstationLetterMapper.insertSelective(userInstationLetter);
    }

    /**
     * 极光推送
     * @param
     */
    public void marketingJpush(MarketingJPushRequestDTO jPushRequestDTO) {
        UserExtInfoResponseDTO userExtInfoResponseDTO=userExtInfoDubboService.queryUserBasicInfo(jPushRequestDTO.getUserId());

        if(userExtInfoResponseDTO==null){
            logger.error("极光推送,目标用户ID={},发生异常,原因是用户扩展信息不存在",jPushRequestDTO.getUserId());
            return;
        }
        if(StringUtils.isEmpty(userExtInfoResponseDTO.getJiuangPushId())){
            logger.error("极光推送,目标用户ID={},发生异常,原因是用户极光推送ID不存在",jPushRequestDTO.getUserId());
            return;
        }
        DeviceType deviceType=transDeviceType(userExtInfoResponseDTO.getLastLoginDevice());
        if(deviceType==null){
            logger.error("极光推送,目标用户ID={},发生异常,原因是用户最后设备类型不是APP(IOS或安卓)",jPushRequestDTO.getUserId());
            return;
        }
        Map<String, String> extraMap = new HashMap<>();
        if (StringUtils.isNotBlank(jPushRequestDTO.getRedirectPage())) {
            extraMap.put("redirectPage", jPushRequestDTO.getRedirectPage());
        }
        if (StringUtils.isNotBlank(jPushRequestDTO.getHtml5Page())) {
            extraMap.put("html5Page", jPushRequestDTO.getHtml5Page());
        }
        PushTarget pushTarget=new PushTarget(userExtInfoResponseDTO.getJiuangPushId(),deviceType);

        jpushClients.sendNotification(jPushRequestDTO.getTitle(),jPushRequestDTO.getContent(),extraMap,pushTarget);
    }
    
    /**
     * 查询用户最新未读的站内信记录
     * 
     * @param userId
     * @return
     */
	public UserInstationLetter getNewestUnreadInstationLetter(String userId) {
        return userInstationLetterMapper.getNewestUnreadInstationLetter(userId);
    } 
}
